<?php

// Loading dependencies
require_once "Exceptions/PokaYokeException.class.php";
require_once "PokaYokeDataHolder.class.php";


class PokaYoke implements ArrayAccess
{
	protected $_data;
	private $_strictMode;


	function __construct( $data, $strictMode = TRUE )
	{
    	if ( ! is_array( $data ) ) {
			throw new PokaYokeException(
				"Cannot define non-array value [ " . gettype( $data )
				. " passed ] as data provider in PokaYoke class"
			);
		}

		$this->_data = $data;
		$this->_strictMode = $strictMode;
	}


	// Generic Access Implementation

	function __get( $offset )
	{
		return $this->get( $offset );
	}


	function __set( $offset, $value )
	{
		$this->set( $offset, $value );
	}


	// ArrayAccess Implementation

	function offsetExists( $offset )
	{
		return $this->has( $offset );
	}

	
	function offsetGet( $offset )
	{
		return $this->get( $offset );
	}


	function offsetSet( $offset, $value )
	{
		$this->set( $offset, $value );
	}


	function offsetUnset( $offset )
	{
		unset( $this->_data[ $offset ] );
	}


	// Data Manipulation Implementation

	public function get( $offset )
	{
		if ( $this->_strictMode && ( ! isset( $this->_data[ $offset ] ) ) ) {
			throw new PokaYokeException(
				"Cannot access unexistent offset [ $offset ] in PokaYoke class"
			);
		}

		if ( is_array( $this->_data[ $offset ] ) ) {
			return new PokaYoke( $this->_data[ $offset ], $this->_strictMode );
		}
		
		return new PokaYokeDataHolder( $this->_data[ $offset ] );
	}


	public function set( $offset, $value )
	{
		$this->_data[ $offset ] = $value;
	}
	
	
	public function has( $offset )
	{
		return ( isset( $this->_data[ $offset ] ) );
	}


	// Accessor Implementation
	
	public function getStrictMode()
	{
		return $this->_strictMode;
	}
}

?>